from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.db import transaction
from django.http import JsonResponse
from django.utils import timezone
from django.urls import reverse
from decimal import Decimal
from django.core.paginator import Paginator

from users.models import Address
from users.forms import AddressForm
from products.models import CartItem
from .models import Order, OrderItem


@login_required
def checkout_view(request):
    """
    结算页面视图 - 显示结算页面
    支持从购物车结算和立即购买两种方式
    计算商品总价、运费和优惠金额
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse: 渲染后的结算页面
    """
    # 检查是否为立即购买
    if request.method == "POST" and request.POST.get('buy_now') == 'true':
        product_id = request.POST.get('product_id')
        quantity = int(request.POST.get('quantity', 1))
        
        from products.models import Product
        try:
            # 获取商品信息
            product = Product.objects.get(id=product_id)
            
            # 检查库存
            if product.stock < quantity:
                messages.error(request, f'商品"{product.name}"库存不足，剩余{product.stock}件')
                return redirect('product_detail', product_id=product_id)
            
            # 创建临时购物车项（不保存到数据库）
            from django.db.models import Model
            class TempCartItem(Model):
                def __init__(self, product, quantity):
                    self.product = product
                    self.quantity = quantity
                    self.selected = True
                    
                @property
                def total_price(self):
                    return self.product.price * self.quantity
            
            cart_items = [TempCartItem(product, quantity)]
            
            # 获取用户地址
            addresses = Address.objects.filter(user=request.user)
            default_address = addresses.filter(is_default=True).first() or addresses.first()
            
            # 如果有地址但没有默认地址值，确保将第一个地址设为默认
            if default_address and not default_address.is_default and addresses.count() > 0:
                first_address = addresses.first()
                if first_address:
                    default_address = first_address
            
            # 计算商品价格
            total_price = product.price * quantity
            
            # 计算运费（可以根据实际业务逻辑调整）
            shipping_fee = Decimal('0.00')
            
            # 计算优惠金额
            discount = Decimal('0.00')
            
            # 计算最终总价
            final_total_price = total_price + shipping_fee - discount
            
            # 构建上下文数据
            context = {
                'cart_items': cart_items,
                'addresses': addresses,
                'default_address': default_address,
                'total_price': total_price,
                'shipping_fee': shipping_fee,
                'discount': discount,
                'final_total_price': final_total_price,
                'buy_now': True,
                'buy_now_product_id': product_id,
                'buy_now_quantity': quantity
            }
            
            return render(request, 'order/checkout.html', context)
            
        except Product.DoesNotExist:
            messages.error(request, '商品不存在')
            return redirect('index')
    
    # 常规结算流程 - 从购物车结算
    cart_items = CartItem.objects.filter(user=request.user, selected=True).select_related('product')
    
    # 如果没有选中商品，返回购物车页面
    if not cart_items.exists():
        messages.warning(request, '请至少选择一件商品进行结算')
        return redirect('view_cart')
    
    # 获取用户地址
    addresses = Address.objects.filter(user=request.user)
    default_address = addresses.filter(is_default=True).first() or addresses.first()
    
    # 如果有地址但没有默认地址值，确保将第一个地址设为默认
    if default_address and not default_address.is_default and addresses.count() > 0:
        first_address = addresses.first()
        if first_address:
            default_address = first_address
    
    # 计算商品总价 - 即使库存不足也显示原价，但在提交订单时会验证
    total_price = sum(item.total_price for item in cart_items)
    
    # 计算运费（可以根据实际业务逻辑调整）
    shipping_fee = Decimal('0.00')  # 修改为Decimal类型
    
    # 计算优惠金额（可以根据实际业务逻辑调整）
    discount = Decimal('0.00')  # 修改为Decimal类型
    
    # 计算最终总价
    final_total_price = total_price + shipping_fee - discount
    
    # 检查商品库存情况 - 仅用于前端显示警告，不阻止结算流程
    for item in cart_items:
        # 更新最新的库存信息
        item.product.refresh_from_db(fields=['stock'])
        
        # if item.product.stock <= 0:
        #     messages.warning(request, f'商品"{item.product.name}"已售罄，下单后将无法支付')
        # elif item.product.stock < item.quantity:
        #     messages.warning(request, f'商品"{item.product.name}"库存不足，当前库存{item.product.stock}件，您需要{item.quantity}件')
    
    # 构建上下文数据
    context = {
        'cart_items': cart_items,
        'addresses': addresses,
        'default_address': default_address,
        'total_price': total_price,
        'shipping_fee': shipping_fee,
        'discount': discount,
        'final_total_price': final_total_price,
    }
    
    return render(request, 'order/checkout.html', context)


@login_required
@transaction.atomic
def create_order(request):
    """
    创建订单视图 - 处理订单提交
    支持从购物车结算和立即购买两种方式创建订单
    使用事务确保数据一致性
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse: 重定向到订单成功页面或支付页面
    """
    if request.method != 'POST':
        return redirect('checkout')
    
    # 获取表单数据
    address_id = request.POST.get('address_id') #地址id
    payment_method = request.POST.get('payment_method') #支付方式
    remark = request.POST.get('remark', '') #备注
    
    # 验证地址和支付方式
    if not address_id or not address_id.strip() or not payment_method:
        messages.error(request, '请选择收货地址和支付方式')
        return redirect('checkout')
    
    # 获取地址
    try:
        address = Address.objects.get(id=address_id, user=request.user)
    except (Address.DoesNotExist, ValueError):
        messages.error(request, '收货地址不存在或无效')
        return redirect('checkout')
    
    # 检查是否为立即购买
    if request.POST.get('buy_now') == 'true':
        from products.models import Product
        product_id = request.POST.get('buy_now_product_id')
        quantity = int(request.POST.get('buy_now_quantity', 1))
        
        try:
            product = Product.objects.get(id=product_id)
            
            # 检查库存
            if product.stock <= 0:
                messages.error(request, f'商品"{product.name}"已售罄，无法下单')
                return redirect('checkout')
                
            if product.stock < quantity:
                messages.error(request, f'商品"{product.name}"库存不足，当前库存{product.stock}件，您需要{quantity}件')
                return redirect('checkout')
            
            # 计算价格
            total_price = product.price * quantity
            shipping_fee = 0.00  # 简化为免运费
            discount = 0.00
            
            # 创建订单
            order = Order.objects.create(
                user=request.user,
                # 直接存储地址信息
                receiver=address.receiver,
                province=address.province,
                city=address.city,
                district=address.district,
                address=address.address,
                zip_code=address.zip_code,
                phone=address.phone,
                total_amount=total_price,
                pay_method=payment_method,
                remark=remark,
                shipping_fee=shipping_fee,
                discount=discount
            )
            
            # 创建订单商品
            OrderItem.objects.create(
                order=order,
                product=product,
                price=product.price,
                quantity=quantity
            )
            
            # 减少库存
            product.stock -= quantity
            product.sales += quantity  # 增加销量
            product.save()
            
            # 如果是货到付款，直接更新订单状态为已付款
            if payment_method == 'cod':
                order.order_status = 'PAID'
                order.save()
                messages.success(request, '订单已创建，等待商家发货')
                return redirect('order_success', order_id=order.order_id)
            
            # 其他支付方式，跳转到支付页面
            messages.success(request, '订单已创建，请完成支付')
            return redirect('payment', order_id=order.order_id)
            
        except Product.DoesNotExist:
            messages.error(request, '商品不存在')
            return redirect('checkout')
    
    # 从购物车创建订单
    cart_items = CartItem.objects.filter(user=request.user, selected=True).select_related('product')
    
    # 如果没有选中商品，返回购物车页面
    if not cart_items.exists():
        messages.warning(request, '请至少选择一件商品进行结算')
        return redirect('view_cart')
    
    # 检查库存
    for item in cart_items:
        # 更新最新的库存信息
        item.product.refresh_from_db(fields=['stock'])
        
        if item.product.stock <= 0:
            messages.error(request, f'商品"{item.product.name}"已售罄，无法下单')
            return redirect('checkout')
            
        if item.product.stock < item.quantity:
            messages.error(request, f'商品"{item.product.name}"库存不足，当前库存{item.product.stock}件，您需要{item.quantity}件')
            return redirect('checkout')
    
    # 计算价格
    total_price = sum(item.total_price for item in cart_items)
    shipping_fee = 0.00  # 简化为免运费
    discount = 0.00
    
    # 创建订单
    order = Order.objects.create(
        user=request.user,
        # 直接存储地址信息
        receiver=address.receiver,
        province=address.province,
        city=address.city,
        district=address.district,
        address=address.address,
        zip_code=address.zip_code,
        phone=address.phone,
        total_amount=total_price,
        pay_method=payment_method,
        remark=remark,
        shipping_fee=shipping_fee,
        discount=discount
    )
    
    # 创建订单商品并减少库存
    for item in cart_items:
        OrderItem.objects.create(
            order=order,
            product=item.product,
            price=item.product.price,
            quantity=item.quantity
        )
        
        # 减少库存
        item.product.stock -= item.quantity
        item.product.sales += item.quantity  # 增加销量
        item.product.save()
    
    # 清空购物车中已购买的商品
    cart_items.delete()
    
    # 如果是货到付款，直接更新订单状态为已付款
    if payment_method == 'cod':
        order.order_status = 'PAID'
        order.save()
        messages.success(request, '订单已创建，等待商家发货')
        return redirect('order_success', order_id=order.order_id)
    
    # 其他支付方式，跳转到支付页面
    messages.success(request, '订单已创建，请完成支付')
    return redirect('payment', order_id=order.order_id)


@login_required
def order_success(request, order_id):
    """
    订单成功页面视图 - 显示订单提交成功信息
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse: 渲染后的订单成功页面
    """
    # 获取订单信息，确保只能查看自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    return render(request, 'order/success.html', {'order': order})


@login_required
def order_list(request):
    """
    订单列表页面视图 - 显示用户的所有订单
    支持按订单状态筛选和分页
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse: 渲染后的订单列表页面
    """
    # 获取状态筛选参数
    status = request.GET.get('status')
    
    # 基础查询，筛选当前用户的订单
    orders_query = Order.objects.filter(user=request.user)
    
    # 根据状态参数筛选
    if status:
        orders_query = orders_query.filter(order_status=status)
    
    # 按创建时间降序排列，预加载订单商品和商品信息减少数据库查询
    orders_query = orders_query.prefetch_related('items__product').order_by('-created_time')
    
    # 分页处理
    paginator = Paginator(orders_query, 5)  # 每页显示5个订单
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)
    
    # 构建上下文数据
    return render(request, 'order/list.html', {
        'orders': page_obj, #当前页的订单
        'current_status': status, #订单当前的状态
        'page_obj': page_obj, #当前页的订单
    })


@login_required
def order_detail(request, order_id):
    """
    订单详情页面视图 - 显示订单的详细信息
    包括订单商品、收货地址、支付方式等
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse: 渲染后的订单详情页面
    """
    # 获取订单信息，确保只能查看自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    return render(request, 'order/detail.html', {'order': order})


@login_required
def payment(request, order_id):
    """
    支付页面视图 - 显示订单支付页面
    提供不同的支付方式选择
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse: 渲染后的支付页面
    """
    # 获取订单信息，确保只能支付自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    
    # 如果订单已支付，重定向到订单详情页
    if order.order_status != 'PENDING':
        return redirect('order_detail', order_id=order.order_id)
    
    return render(request, 'order/payment.html', {'order': order})


@login_required
def update_payment_method(request, order_id):
    """
    更新订单支付方式视图 - 修改订单的支付方式
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    if request.method != 'POST':
        return redirect('payment', order_id=order_id)
    
    # 获取订单信息，确保只能修改自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    
    # 如果订单已支付，重定向到订单详情页
    if order.order_status != 'PENDING':
        return redirect('order_detail', order_id=order.order_id)
    
    # 获取新的支付方式
    payment_method = request.POST.get('payment_method')
    # 验证支付方式是否有效
    if payment_method in ['alipay', 'wechat', 'bank', 'cod']:
        order.pay_method = payment_method
        order.save()
        
        # 检查是否为AJAX请求
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                'success': True,
                'message': '支付方式已更新'
            })
    
    return redirect('payment', order_id=order.order_id)


@login_required
def pay_order(request, order_id):
    """
    模拟支付完成视图 - 处理订单支付请求
    将订单状态更新为已支付
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse: 重定向到订单成功页面
    """
    if request.method != 'POST':
        return redirect('payment', order_id=order_id)
    
    # 获取订单信息，确保只能支付自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    
    # 如果订单已支付，重定向到订单详情页
    if order.order_status != 'PENDING':
        return redirect('order_detail', order_id=order.order_id)
    
    # 模拟支付成功，更新订单状态
    order.order_status = 'PAID'
    order.pay_time = timezone.now()
    # 生成交易号
    order.trade_no = f"PAY{timezone.now().strftime('%Y%m%d%H%M%S')}"
    order.save()
    
    messages.success(request, '支付成功')
    return redirect('order_success', order_id=order.order_id)


@login_required
def cancel_order(request, order_id):
    """
    取消订单视图 - 取消未支付的订单
    将订单状态更新为已取消，并恢复商品库存
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse: 重定向到订单列表页面
    """
    # 获取订单信息，确保只能取消自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    
    # 只有待付款状态的订单才能取消
    if order.order_status != 'PENDING':
        messages.error(request, '只有待付款的订单可以取消')
        return redirect('order_detail', order_id=order.order_id)
    
    # 更新订单状态为已取消
    order.order_status = 'CANCELLED'
    order.save()
    
    # 恢复库存和销量
    for item in order.items.all():
        product = item.product
        product.stock += item.quantity
        product.sales -= item.quantity
        product.save()
    
    messages.success(request, '订单已取消')
    return redirect('order_list')


@login_required
def confirm_receipt(request, order_id):
    """
    确认收货视图 - 确认已发货订单的收货
    将订单状态更新为已完成
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse: 重定向到订单详情页面
    """
    # 获取订单信息，确保只能确认自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    
    # 只有配送中状态的订单才能确认收货
    if order.order_status != 'SHIPPING':
        messages.error(request, '只有配送中的订单才能确认收货')
        return redirect('order_detail', order_id=order.order_id)
    
    # 更新订单状态为已完成
    order.order_status = 'COMPLETED'
    order.receive_time = timezone.now()
    order.save()
    
    messages.success(request, '订单已完成，感谢您的购买！')
    return redirect('order_detail', order_id=order.order_id)


@login_required
def add_address_checkout(request):
    """
    在结算页面添加收货地址视图
    支持AJAX请求和普通表单提交
    
    Args:
        request: HttpRequest对象
        
    Returns:
        HttpResponse或JsonResponse: 重定向或JSON响应
    """
    if request.method == 'POST':
        form = AddressForm(request.POST)
        if form.is_valid():
            # 创建新地址并关联到当前用户
            address = form.save(commit=False)
            address.user = request.user
            address.save()
            
            # 检查是否为AJAX请求
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': '地址添加成功！',
                    'address_id': address.id
                })
            
            messages.success(request, '地址添加成功！')
            return redirect('checkout')
        else:
            # 表单验证失败
            error_msg = '表单验证失败，请检查您的输入！'
            for field, errors in form.errors.items():
                error_msg += f" {field}: {', '.join(errors)}"
            
            # 检查是否为AJAX请求
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': False,
                    'message': error_msg,
                    'errors': form.errors
                })
                
            messages.error(request, error_msg)
            
    return redirect('checkout')


@login_required
def get_addresses(request):
    """
    获取用户地址列表视图
    用于AJAX更新结算页面的地址列表
    
    Args:
        request: HttpRequest对象
        
    Returns:
        JsonResponse: 包含地址列表的JSON响应
    """
    addresses = Address.objects.filter(user=request.user)
    address_list = []
    
    for address in addresses:
        address_list.append({
            'id': address.id,
            'receiver': address.receiver,
            'province': address.province,
            'city': address.city,
            'district': address.district,
            'address': address.address,
            'phone': address.phone,
            'zip_code': address.zip_code,
            'is_default': address.is_default
        })
    
    return JsonResponse({
        'success': True,
        'addresses': address_list
    })


@login_required
def comment_order_item(request, order_item_id):
    """
    评价订单商品视图 - 为已完成订单的商品添加评价
    验证用户权限和订单状态，创建商品评价
    
    Args:
        request: HttpRequest对象
        order_item_id: 订单商品ID
        
    Returns:
        HttpResponse: 重定向到订单详情页面
    """
    from products.models import Comment
    
    # 获取订单商品
    order_item = get_object_or_404(OrderItem, id=order_item_id)
    
    # 验证用户是否有权限评价
    if order_item.order.user != request.user:
        messages.error(request, '您没有权限评价此商品')
        return redirect('order_list')
    
    # 验证订单状态
    if order_item.order.order_status != 'COMPLETED':
        messages.error(request, '只有已完成的订单才能评价')
        return redirect('order_detail', order_id=order_item.order.order_id)
    
    # 验证评价状态
    if order_item.comment_status == 'COMMENTED':
        messages.error(request, '此商品已评价过')
        return redirect('order_detail', order_id=order_item.order.order_id)
    
    if request.method == 'POST':
        # 获取评价内容
        rating = int(request.POST.get('rating', 5))
        content = request.POST.get('content', '')
        
        # 创建评价
        Comment.objects.create(
            user=request.user,
            product=order_item.product,
            content=content,
            rating=rating
        )
        
        # 更新订单商品评价状态
        order_item.comment_status = 'COMMENTED'
        order_item.save()
        
        messages.success(request, '评价成功')
        return redirect('order_detail', order_id=order_item.order.order_id)
    
    return redirect('order_list')


@login_required
def rebuy_order(request, order_id):
    """
    再次购买订单视图 - 将订单中的商品重新添加到购物车
    检查商品库存状态，添加可购买的商品到购物车
    
    Args:
        request: HttpRequest对象
        order_id: 订单号
        
    Returns:
        HttpResponse: 重定向到购物车页面
    """
    from products.models import CartItem, Product
    
    # 获取订单信息，确保只能再次购买自己的订单
    order = get_object_or_404(Order, order_id=order_id, user=request.user)
    added_count = 0
    
    # 遍历订单中的所有商品
    for item in order.items.all():
        # 检查商品是否还存在且有库存
        if item.product.status == 1 and item.product.stock > 0:
            # 添加到购物车，数量不超过当前库存
            quantity = min(item.quantity, item.product.stock)
            
            # 获取或创建购物车项
            cart_item, created = CartItem.objects.get_or_create(
                user=request.user,
                product=item.product,
                defaults={'quantity': quantity}
            )
            
            # 如果购物车中已有该商品，增加数量
            if not created:
                cart_item.quantity = min(cart_item.quantity + quantity, item.product.stock)
                cart_item.save()
            
            added_count += 1
    
    # 显示添加结果消息
    if added_count > 0:
        messages.success(request, f'已将{added_count}件商品添加到购物车')
    else:
        messages.warning(request, '没有可添加的商品')
    
    # 重定向到购物车页面
    return redirect('view_cart') 